package com.example.fuzzy;
import java.util.*;

 
public class VariableLinguistica 
{
	private String thisLVname;
	private java.util.Hashtable storage;
	private double input_value;
	private java.util.Vector for_defuzzification;
	private java.util.Vector defuzzificacionAuxiliar;

	private double minimo;
	private double maximo;
	private static double minimoConjuntosBajo;
	private static double minimoConjuntosAlto;
	private static double minimoConjuntosMedio;



 
public void add(FuncionMembresia mFunction) 
{
	double [] range = mFunction.getRange();
	storage.put(mFunction.getName(),mFunction);
	if(range[0]<minimo)	
		minimo=range[0];
	if(range[3]>maximo)	
		maximo=range[3];
}
 
public void add(String name,double start, double left_top, double right_top, double finish) 
{
	double [] range = {start,left_top,right_top,finish};
	FuncionMembresia temp = new FuncionMembresia(name,range);
	storage.put(name,temp);

	if(start<minimo)	
		minimo=start;
	if(finish>maximo)	
		maximo=finish;
}
 
public double defuzzify() //throws ReglasNoLanzadas 
{
	auxiliar();
	int lanzadas = for_defuzzification.size();

//	if(lanzadas == 0)
//		{
//			ReglasNoLanzadas e = new ReglasNoLanzadas("Reglas no lanzadas "+this.thisLVname);
//			throw e;
//		}

	double pasos = Math.abs((maximo-minimo)/100);

	double [] alturas;
	double [] sum = new double [100];

	
	
	for(int i=0; i<(lanzadas-1); i+=2)
	{
		if (((Double)for_defuzzification.elementAt(i+1)).doubleValue() != 0){
			alturas = this.getMembershipFunctionByName((String)for_defuzzification.elementAt(i))
						.plot(minimo,maximo,100);

		double altura = ((Double)for_defuzzification.elementAt(i+1)).doubleValue();
		for(int j=0; j<100; j++)	
		    {
			sum[j]+=alturas[j]*altura;
			}
		}
	}
			
	//Metodo del centroide
	double nominador = 0.0;
	double denominador = 0.0;
	for(int i=0; i<100; i++)
	{
		nominador+=(minimo+pasos*i)*sum[i];
		denominador+=sum[i];
	}

	return nominador/denominador;
}
 
public java.util.Vector getFor_defuzzification() {
	return for_defuzzification;
}

public void setFor_defuzzification(java.util.Vector for_defuzzification) {
	this.for_defuzzification = for_defuzzification;
}

public String getLVName() 
{
	return thisLVname;
}
 
public FuncionMembresia getMembershipFunctionByName(String name) 
{
	return (FuncionMembresia)storage.get(name);
}
 
public double is(String name) 
{
	FuncionMembresia m = this.getMembershipFunctionByName(name);
	
	if(m!=null)		
		return m.fuzzificacion(input_value);
	else			
		return -1;
}
 
public VariableLinguistica(String name) 
{ 
	super();
	this.thisLVname = name;
	storage = new java.util.Hashtable();
	for_defuzzification = new java.util.Vector();
	defuzzificacionAuxiliar = new java.util.Vector();
}
 
 
public void setInputValue(double value) 
{
	this.input_value = value;
}


public void set(String name, double value) throws TesteoReglasExcepcion 
{


	if(getMembershipFunctionByName(name)!=null)		
		for_defuzzification.addElement(name);
	else 
		throw new TesteoReglasExcepcion("Wrong name of a membership function");
	
	for_defuzzification.addElement(new Double(value));
}
 
public void setLVName(String name) 
{
	thisLVname = name;
}


	public double getMinimoConjuntosMedio() {
		return minimoConjuntosMedio;
	}

	public void setMinimoConjuntosMedio(double minimoConjuntosMedio) {
		this.minimoConjuntosMedio = minimoConjuntosMedio;
	}

	public double getMinimoConjuntosBajo() {
		return minimoConjuntosBajo;
	}
	public void setMinimoConjuntosBajo(double minimoConjuntosBajo) {
		this.minimoConjuntosBajo = minimoConjuntosBajo;
	}
	
	public double getMinimoConjuntosAlto() {
		return minimoConjuntosAlto;
	}
	public void setMinimoConjuntosAlto(double minimoConjuntosAlto) {
		this.minimoConjuntosAlto = minimoConjuntosAlto;
	}
	
//	public void maximoAltoyBajo(){
//		
//		for(int i=0; i<for_defuzzification.size()-1; i+=2){
//			String f = (String) for_defuzzification.elementAt(i);
//			Double a = ((Double)for_defuzzification.elementAt(i+1)).doubleValue();
//			
//			if (f.equalsIgnoreCase("alto") && getMinimoConjuntosAlto()<a){
//				setMinimoConjuntosAlto(a);
//			}
//			
//			if (f.equalsIgnoreCase("bajo") && getMinimoConjuntosBajo()<a){
//				setMinimoConjuntosBajo(a);
//			}
//			
//			if (f.equalsIgnoreCase("medio") && getMinimoConjuntosMedio()<a){
//				setMinimoConjuntosMedio(a);
//			}
//			
//		}
//		
//	}
//	
//	
//	public void localicarValores(){
//		
//		boolean anadidoAlto,anadidoBajo,anadidoMedio;
//		anadidoAlto=anadidoBajo=anadidoMedio=false;
//		for(int i=0; i<for_defuzzification.size()-1; i+=2){
//			String f = (String) for_defuzzification.elementAt(i);
//			Double a = ((Double)for_defuzzification.elementAt(i+1)).doubleValue();
//		
//			if (f.equalsIgnoreCase("alto") && a==getMinimoConjuntosAlto() && !anadidoAlto){
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i));
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i+1));
//				anadidoAlto = true;
//			}
//			
//			if (f.equalsIgnoreCase("bajo") && a==getMinimoConjuntosBajo() && !anadidoBajo){
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i));
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i+1));
//				anadidoBajo = true;
//			}
//			
//			if (f.equalsIgnoreCase("medio") && a==getMinimoConjuntosMedio() && !anadidoMedio){
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i));
//				defuzzificacionAuxiliar.addElement(for_defuzzification.get(i+1));
//				anadidoMedio = true;
//			}
//			
//			
//	}
//	
//	}
//	
	public void reset() 
	{
		for_defuzzification.removeAllElements();
		minimoConjuntosBajo=0;
		minimoConjuntosAlto=0;
		minimoConjuntosMedio=0;

	}
	
//	
//	public void copiarVectores(){
//		
//		for_defuzzification.removeAllElements();
//		for_defuzzification = (Vector) defuzzificacionAuxiliar.clone();
//		defuzzificacionAuxiliar.removeAllElements();
//	}

	public void auxiliar() {
		
		try{
			set("alto", getMinimoConjuntosAlto());
	     	set("medio", getMinimoConjuntosMedio());
			set("bajo", getMinimoConjuntosBajo());
		}
		catch(Exception E){}
		}
	
	public VariableLinguistica(){}
	
}
	
